#include <stdio.h>

struct A
{
    virtual void vfa() { printf("Calling A::vfa, this:%p\n", this); }
    ~A() { printf("Calling A::~A, this:%p\n", this); }
};
struct B
{
    virtual void vfb() { printf("Calling C::vfb, this:%p\n", this); }
    virtual ~B() { printf("Calling C::~C. this:%p\n", this); }
};
struct C : A, B
{
    virtual void vfa() { printf("Calling C::vfa, this:%p\n", this); }
    virtual void vfb() { printf("Calling C::vfb, this:%p\n", this); }
    ~C() { printf("Calling C::~C, this:%p\n", this); }
};

struct D
{
    virtual void vfd() { printf("Calling D::vfd, this:%p\n", this); }
    ~D() { printf("Calling D::~D, this:%p\n", this); }
};


struct E : D, C
{
    virtual void vfa() { printf("Calling E::vfa, this:%p\n", this); }
    virtual void vfb() { printf("Calling E::vfb, this:%p\n", this); }
    virtual void vfd() { printf("Calling E::vfd, this:%p\n", this); }
};

// ed|ca|b

int main(void)
{
    auto e = new E;
    auto a = dynamic_cast<A*>(e);
    auto b = dynamic_cast<B*>(e);
    auto c = dynamic_cast<C*>(e); //RTTI
    auto c2 =(C*)(e);
    auto c4 = static_cast<C*>(e);
    auto c3 = reinterpret_cast<C*>(e);
    auto d = dynamic_cast<D*>(e);
    printf("a:%p, b:%p, c:%p, c2:%p, c3:%p, c4:%p, d:%p, e:%p\n", a, b, c, c2, c3, c4, d, e);
    a->vfa();
    b->vfb();
    c->vfa();
    c->vfb();
    d->vfd();
    delete c;
    return 0;
}
